<?php
error_reporting(E_ALL ^ E_NOTICE^ E_WARNING);
ini_set('display_errors', '0'); 
date_default_timezone_set('Asia/Shanghai');

class ElemeCommon
{
    public $app_key;
    public $app_secret;
    public $api_request_url;
    public $token;
    public $log;
    public $callback_url;
    public $token_url;
    
    public function __construct()
    {
        //测试环境
        $this->app_key = 'EbcWuc8BP8';
        $this->app_secret = 'c588caea59f16a2f659f3074372bda03';
        $this->api_request_url = 'https://open-api-sandbox.shop.ele.me/api/v1/';
        $this->log = '';

        $this->token = ;
        $this->callback_url = 'http://pingtai.kfyao.com/ele/ele/ele2.php';
        $this->token_url = 'https://open-api-sandbox.shop.ele.me/token';
        $this->authorize_url = 'https://open-api-sandbox.shop.ele.me/authorize';
        
        //正式环境
        // $this->app_key = 'WYS3wPel5y';
        // $this->app_secret = 'e0efa0404a31887487aa300d5d2ae029';
        // $this->api_request_url = 'https://open-api.shop.ele.me/api/v1/';
        // $this->token = '04d7b452f6c01e17140a799150eb535b';
        // $this->callback_url = 'http://pingtai.kfyao.com/ele/ele/ele2.php';
        // $this->token_url = 'https://open-api.shop.ele.me/token';
        // $this->authorize_url = 'https://open-api.shop.ele.me/authorize';
    }

    public function getToken()
    {
        $GetElemeToken = new GetElemeToken();
        $token = $GetElemeToken->getToken($this->app_key, $this->app_secret, true);

        return $token;
    }

    public function create_uuid()
    {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );    
    }

    /**
    * 生成签名
    */
    public function generate_signature($protocol)
    {
        $merged = array_merge($protocol['metas'], $protocol['params']);
        ksort($merged);
        $string = "";
        foreach ($merged as $key => $value) {
            $string .= $key . "=" . json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        }
        $splice = $protocol['action'] . $this->token . $string . $this->app_secret;

        $encode = mb_detect_encoding($splice, array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));
        if ($encode != null) {
            $splice = mb_convert_encoding($splice, 'UTF-8', $encode);
        }

        return strtoupper(md5($splice));
    }

    /**
     * 生成授权url
     * @param $state 状态码，通常是随机的UUID，授权成功后会原样返回，可以用于校验
     * @param $scope 授权范围，默认情况下填写"all"
     * @param $callback_url 回调地址
     * @return string
     */
    public function get_auth_url()
    {
        $url = $this->authorize_url;
        $callback = $this->callback_url;

        $data = array(
            "response_type" => "code",
            "client_id" => $this->app_key,
            "redirect_uri" => urlencode($callback),
            "state" => $this->create_uuid(),
            "scope" => 'all'
        );

        return sprintf("%s?%s", $url, http_build_query($data));
    }

    /**
     * 通过授权码获取token
     * @param $code 授权码
     * @param $callback_url 回调地址
     * @return mixed
     */
    public function get_token_by_code($code)
    {
        $body = array(
            "grant_type" => "authorization_code",
            "code" => '123',
            "redirect_uri" => $this->callback_url,
            "client_id" => $this->app_key
        );
        $response = $this->request($body);
        return $response;
    }

    /*
        获取公共参数
        params
            action 接口地址
            params 传输的参数
    */
    public function getPostData($action = '', $params = array())
    {
        $data = array(
            "nop" => '1.0.0',
            "id" => $this->create_uuid(),
            "action" => $action,
            "token" => $this->token,
            "metas" => array(
                "app_key" => $this->app_key,
                "timestamp" => time(),
            ),
            "params" => $params
        );

        $data['signature'] = $this->generate_signature($data);

        return $data;
    }


    public static function doPost($url, $param, $method = "POST")
    {
        // echo 'Request url is ' . $url . PHP_EOL;
        if (empty($url) or empty($param)) {
            throw new InvalidArgumentException('Params is not of the expected type');
        }
        // 验证url合法性
        if (!empty($param) and is_array($param)) {
            $param = urldecode(json_encode($param));
        } else {
            // $param = urldecode(strval($param));
            $param = strval($param);
        }
        // var_dump($param);die;
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        // curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);     //  不进行ssl 认证

        if (strcmp($method, "POST") == 0) {  // POST 操作
            curl_setopt($ch, CURLOPT_POST, true);
        } else if (strcmp($method, "DELETE") == 0) { // DELETE操作
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        } else {
            throw new InvalidArgumentException('Please input correct http method, such as POST or DELETE');
        }

        curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: Application/json'));
        $result = curl_exec($ch);
        $result = json_decode($result,true);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if (!empty($result) and $code == '200') {
            return $result;
        }
        return false;
    }

     public function DLOG($log_content='', $log_level='', $log_name='')
    { 

        if(empty($log_level)||empty($log_content))
            return;
        
        
        if(empty($log_name) && $log_level == 'run')
            $log_name = 'run';

        $log_dir = "/mnt/logs/";
        $log_file = $log_dir.$log_name.".".date('Y-m-d').".log";
        
        //默认每行日志必写的内容，统一在这里处理
        // ZHANGXI 2015/1/7 for regular
        $time = sprintf("%8s.%03d",date('H:i:s'),floor(microtime()*1000));
        //$time = date('H:i:s').".".floor(microtime()*1000);
        $ip = sprintf("%15s",$_SERVER["REMOTE_ADDR"]);

        $id =   "req-Fn";

        $path_arr = explode("/", $_SERVER['REQUEST_URI']);

        $content_prefix = "[ ".$time." ".$ip." ".$id." ".$log_level." ".$path_arr[1]." ".$path_arr[2]." ] ";

        error_log($content_prefix.$log_content." [".getmypid()."]\n", 3, $log_file);
        return true;
    }

    private function request($body)
    {
        if ($this->log != null) {
            $this->log->info("request data: " . json_encode($body));
        }

        $ch = curl_init($this->token_url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->get_headers());
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($body));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, "eleme-openapi-php-sdk");
        curl_setopt($ch, CURLOPT_ENCODING, "gzip");
        $request_response = curl_exec($ch);
        if (curl_errno($ch)) {
            if ($this->log != null) {
                $this->log->error("error: " . curl_error($ch));
            }
            throw new Exception(curl_error($ch));
        }
        $response = json_decode($request_response);
        if (is_null($response)) {
            throw new Exception("illegal response :" . $request_response);
        }
        if (isset($response->error)) {
            throw new IllegalRequestException(json_encode($response));
        }

        if ($this->log != null) {
            $this->log->info("response: " . json_encode($response));
        }
        return $response;
    }

    private function get_headers()
    {
        return array(
            "Authorization: Basic " . base64_encode(urlencode($this->app_key) . ":" . urlencode($this->app_secret)),
            "Content-Type: application/x-www-form-urlencoded; charset=utf-8",
            "Accept-Encoding: gzip");
    }
}